package com.base.service;

import com.alibaba.fastjson.JSONObject;
import com.base.entity.OrderEntity;
import com.base.repository.OrderRepository;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class ProducerService {

    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    public String saveOrder() {
        // 提前生成我们的订单id
        String orderId = System.currentTimeMillis() + "";

        /**
         * 1.提前生成我们的半消息
         *
         * 2.半消息发送成功之后，在执行我们的本地事务
         *
         */
        OrderEntity orderEntity = createOrder(orderId);
        String msg = JSONObject.toJSONString(orderEntity);
        MessageBuilder<String> stringMessageBuilder = MessageBuilder.withPayload(msg);
        stringMessageBuilder.setHeader("msg", msg);
        Message message = stringMessageBuilder.build();


        // 该消息不允许被消费者消费
        rocketMQTemplate.sendMessageInTransaction("myProducer1",
                "orderTopic", message, null);
        return orderId;

    }

    /*
     rocketMQTemplate.sendMessageInTransaction(txProducerGroup, destination, message, arg)方法的逻辑包括了分布式事务的前四步:
1.发送一个half message去RocketMQ
2.RocketMQ收到ha1f message后，会给应用响应success
3.应用接着去执行RocketMQLocalTransactionListener实现类的executeLocalTransaction方法，这个方法里面执行的逻辑中带有本地的事务；
4.如果本地的事务执行成功，那么就通知RocketMQ对之前的half message进行COMMIT;
如果本地的事务执行失败，那么就通知RocketMQ对之前的ha1f message进行ROLLBACK;

注意：这里的结果TransactionSendResult，指的是RocketMQ对那一条half message的是否处理完毕; 不管是COMMIT，还是ROLLBACK，都算处理完毕。
即：只要第四步通知到了RocketMQ，不论是对half message进行COMMIT，还是进行ROLLBACK;这里sendResult.getSendStatus()都为SendStatus.SEND_OK。
换种说法:如果这里的sendResult.getSendStatus()值为SendStatus.SEND_OK，那么代表的是: 分布式事务的前四步是不是成功执行完毕了。整个事务COMMIT，算是成功执行完毕；整个事务ROLLBACK也算是成功执行完毕。
     */



    public OrderEntity createOrder(String orderId) {
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderName("order name");
        orderEntity.setOrderCreatetime(new Date());
        // 价格是300元
        orderEntity.setOrderMoney(300d);
        // 状态为 未支付
        orderEntity.setOrderState(0);
        Long commodityId = 30L;
        // 商品id
        orderEntity.setCommodityId(commodityId);
        orderEntity.setOrderId(orderId);
        return orderEntity;
    }
}
